# 合并两个有序链表: https://leetcode-cn.com/problems/merge-two-sorted-lists/

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

# 之前的写发，完全模拟合并排需中的 合并操作
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 设立一个首元结点（最好使用 dumpy表示，这是以前写的代码没注意这些）
        h = ListNode()
        cur = h
        while l1 and l2:
            if l1.val < l2.val:
                p1 = l1
                l1 = l1.next
                cur.next = p1
            else:
                p2 = l2
                l2 = l2.next
                cur.next = p2
            cur = cur.next
    
        # 当其中一个为None了，判断那个不为空，继续添加
        while l1:
            p1 = l1
            l1 = l1.next
            cur.next = p1
            cur = cur.next
         
        while l2:
            p2 = l2
            l2 = l2.next
            cur.next = p2
            cur = cur.next
        
        return h.next




# 上面的判断异常繁琐，好几个 while循环，这里优化一下
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 设立一个首元结点
        h = ListNode()
        cur = h
        while l1 or l2:
            # 值的范围为 [-100, 100], 那么当没有节点时，就取 101
            a = l1.val if l1 else 101
            b = l2.val if l2 else 101

            if a < b:
                p1 = l1
                l1 = l1.next
                cur.next = p1
            else:
                p2 = l2
                l2 = l2.next
                cur.next = p2
            cur = cur.next
        
        return h.next


# 其实按照链表的特性，还可以按照最上面的写法
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        h = ListNode()
        cur = h
        while l1 and l2:
            if l1.val < l2.val:
                p1 = l1
                l1 = l1.next
                cur.next = p1
            else:
                p2 = l2
                l2 = l2.next
                cur.next = p2
            cur = cur.next
    
        # 直接链接就行了， 链表根本不需要while循环遍历
        if l1: cur.next = l1
        if l2: cur.next = l2
        
        return h.next



# 下面我自己递归的写法
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        """
            使用递归解题
        """
        def merge(l1, l2):
            # 递归终止条件， 一个为None，直接返回剩余
            if not l1:
                return l2
            elif not l2:
                return l1

            # 1. 寻找当前节点
            # 2. 回溯时，确定其next指向
            # 3. 返回当前节点
            if l1.val < l2.val:
                l1.next = merge(l1.next, l2)
                return l1
            else:
                l2.next = merge(l1, l2.next)
                return l2

        return merge(l1, l2)



